﻿using System;
using System.Collections.Generic;
using SocialFront.Entities;
using SocialFront.Providers.Comment;
using SocialFront.Providers.Member;
using SocialFront.Providers.User;
using umbraco.cms.businesslogic.relation;
using umbraco.cms.businesslogic.web;
using umbraco.presentation.nodeFactory;
using apiRelation = umbraco.cms.businesslogic.relation;

namespace SocialFront.Provider.Umbraco
{
    public class UmbracoComment : CommentBase
    {
        public override Comment CreateComment(Comment comment)
        {
            //apiRelation.Relation[] relations = apiRelation.Relation.GetRelations(comment.Member.Id, apiRelation.RelationType.GetByAlias("relateMemberToDocType"));
            //if (relations.Length > 1)
            //{
            //    throw new Exception("Too many relateMemberToBlogDocType relationships in database for user " + blog.Member.LoginName);
            //}
            Document newDocument = Document.MakeNew(
                comment.Title,
                DocumentType.GetByAlias("sfComment"), 
                UserProvider.Provider.GetSystemUser(), 
                Node.GetCurrent().Id);

            newDocument.getProperty("title").Value = comment.Title;
            newDocument.getProperty("pageTitle").Value = comment.Title;
            newDocument.getProperty("content").Value = comment.Content;
            newDocument.Save();

            // NOTE: Insert check for if the blog has been moderated
            newDocument.Publish(UserProvider.Provider.GetSystemUser());
            umbraco.library.UpdateDocumentCache(newDocument.Id);

            RelationType relationTypeM2Dt = RelationType.GetByAlias("relateMemberToDocType");
            Member member = MemberProvider.Provider.GetCurrentMember();
            apiRelation.Relation.MakeNew(member.Id, newDocument.Id, relationTypeM2Dt,
                                         member.LoginName + " to " + comment.Title);

            comment = ConvertNodeToComment(new Node(newDocument.Id));

            return comment;
        }

        public override Comment UpdateComment(Comment comment)
        {
            throw new NotImplementedException();
        }

        public override void DeleteComment(int id)
        {
            Document document = new Document(id);
            document.delete();
        }

        public override void DeleteComment(Comment comment)
        {
            DeleteComment(comment.Id);
        }

        public override IList<Comment> GetEntityComments()
        {
            return GetEntityComments(c => c.CreatedDate);
        }

        public override IList<Comment> GetEntityComments<T>(Func<Comment, T> sortField)
        {
            return GetEntityComments(null, sortField);
        }

        public override IList<Comment> GetEntityComments<T>(int? pageSize, Func<Comment, T> sortField)
        {
            return GetEntityComments(null, null, sortField);
        }

        public override IList<Comment> GetEntityComments<T>(int? pageSize, int? page, Func<Comment, T> sortField)
        {
            int total = 0;
            return GetEntityComments(null, null, out total, sortField);
        }

        public override IList<Comment> GetEntityComments<T>(int? pageSize, int? page, out int total, Func<Comment, T> sortField)
        {
            total = 0;
            Node node = Node.GetCurrent();
            IList<Node> nodeList = new List<Node>();
            foreach (Node childNode in node.Children)
            {
                if (childNode.NodeTypeAlias == "sfComment")
                    nodeList.Add(childNode);
            }
            if (nodeList.Count > 0)
                total = nodeList.Count;
            return ConvertNodesToComments(nodeList);
        }

        public override IList<Comment> GetCommentsByMember(int id)
        {
            throw new NotImplementedException();
        }

        public override IList<Comment> GetCommentsByMember(Member member)
        {
            throw new NotImplementedException();
        }

        public override IList<Comment> GetCommentsByMember<T>(int id, Func<Comment, T> sortField)
        {
            throw new NotImplementedException();
        }

        public override IList<Comment> GetCommentsByMember<T>(Member member, Func<Comment, T> sortField)
        {
            throw new NotImplementedException();
        }

        public override IList<Comment> GetCommentsByMember<T>(int id, int? pageSize, Func<Comment, T> sortField)
        {
            throw new NotImplementedException();
        }

        public override IList<Comment> GetCommentsByMember<T>(Member member, int? pageSize, Func<Comment, T> sortField)
        {
            throw new NotImplementedException();
        }

        public override IList<Comment> GetCommentsByMember<T>(int id, int? pageSize, int? page, Func<Comment, T> sortField)
        {
            throw new NotImplementedException();
        }

        public override IList<Comment> GetCommentsByMember<T>(Member member, int? pageSize, int? page, Func<Comment, T> sortField)
        {
            throw new NotImplementedException();
        }

        public override IList<Comment> GetCommentsByMember<T>(int id, int? pageSize, int? page, out int total, Func<Comment, T> sortField)
        {
            throw new NotImplementedException();
        }

        public override IList<Comment> GetCommentsByMember<T>(Member member, int? pageSize, int? page, out int total, Func<Comment, T> sortField)
        {
            throw new NotImplementedException();
        }

        private static Comment ConvertNodeToComment(Node node)
        {
            Comment comment = new Comment();
            comment.ModifiedDate = node.UpdateDate;
            comment.CreatedDate = node.CreateDate;
            comment.Id = node.Id;
            comment.Title = node.GetProperty("title").Value;
            comment.Content = node.GetProperty("content").Value;
            comment.ParentId = node.Parent.Id;
            if (node.GetProperty("enabled").Value != "")
            {
                comment.Enabled = Convert.ToBoolean(Convert.ToInt32(node.GetProperty("enabled").Value));
            }
            apiRelation.Relation[] relations = apiRelation.Relation.GetRelations(node.Id, RelationType.GetByAlias("relateMemberToDocType"));
            if (relations.Length == 0)
            {
                throw new Exception("No relateMemberToDocType relationship found!");
            }
            if (relations.Length > 1)
            {
                throw new Exception("Too many relateMemberToDocType relationships in database");
            }
            Member member = MemberProvider.Provider.GetMemberById(relations[0].Parent.Id);
            comment.Member = member;

            return comment;
        }

        private static IList<Comment> ConvertNodesToComments(IList<Node> nodes)
        {
            IList<Comment> comments = new List<Comment>();
            foreach (Node node in nodes)
            {
                comments.Add(ConvertNodeToComment(node));
            }
            return comments;
        }
    }
}